
#include <BDrag>
#include <BFile>
#include <BEntry>
#include <BFont>
#include <BTableItem>
#include <BListItem>
#include <BShortcut>
#include <BMessageBox>
#include <BReadWrite>
#include <BXmlDocument>
#include <BSonDocument>
#include <BSystem>
#include <BApplication>

#include "AlignWidget.h"
#include "LineStripe.h"
#include "CutoffImageDialog.h"
#include "CutoffOperation.h"
#include "DragLayerFilter.h"
#include "PaintOperation.h"
#include "EraseOperation.h"
#include "ImageLayer.h"
#include "LineStripePanel.h"
#include "MainWindow.h"

MainWindow::MainWindow()
{
	BShortcut* copyShortcut = new BShortcut("ctrl+c", this);
	BShortcut* pasteShortcut = new BShortcut("ctrl+v", this);
	connect(copyShortcut, Signal_Triggered, &MainWindow::slotCopyShortcutTriggered);
	connect(pasteShortcut, Signal_Triggered, &MainWindow::slotPasteShortcutTriggered);

	_insertMenu = new BMenu("Insert");
	_insertMenu->setName("insert");
	_insertMenu->addAction("Image");
	_insertMenu->addAction("Label");
	_insertMenu->addAction("Stripe");

	_canvasMenu = new BMenu("Canvas");
	_canvasMenu->setName("canvas");
	{
		_canvasWidget = new CanvasWidget();
		BLayout* layout = new BLayout(_canvasMenu);
		layout->setWidget(_canvasWidget);
	}

	_modifyMenu = new BMenu("Modify");
	{
		_modifyMenu->addAction("replace");
	}

	_pixmapMenu = new BMenu("Main");
	_pixmapMenu->setName("area");
	{
		BAction* turnHorAction = _pixmapMenu->addAction("turn-hor");
		BAction* turnVerAction = _pixmapMenu->addAction("turn-ver");
		BAction* rollLeftAction = _pixmapMenu->addAction("roll-left");
		BAction* rollRightAction = _pixmapMenu->addAction("roll-right");
		BMenu* alignMenu = _pixmapMenu->addMenu("Align To");
		alignMenu->setName("align-to");
		{
			AlignWidget* alignWidget = new AlignWidget();
			BLayout* vlayout = new BLayout(alignMenu);
			vlayout->setWidget(alignWidget);
			connect(alignWidget, "button-clicked", &MainWindow::slotAlignButtonClicked);
		}

		connect(turnHorAction, Signal_Triggered, &MainWindow::slotTurnHorActionTriggered);
		connect(turnVerAction, Signal_Triggered, &MainWindow::slotTurnVerActionTriggered);
		connect(rollLeftAction, Signal_Triggered, &MainWindow::slotRollLeftActionTriggered);
		connect(rollRightAction, Signal_Triggered, &MainWindow::slotRollRightActionTriggered);
	}

	BHBoxLayout* toolsLayout = new BHBoxLayout();
	toolsLayout->setSpacing(2);
	{
		_openButton = new BButton("Open");
		_openButton->setForm(Form_IconAlone);
		_openButton->setShortcut("CTRL+O");

		_saveButton = new BButton("Save");
		_saveButton->setForm(Form_IconAlone);
		_saveButton->setShortcut("CTRL+S");

		_resetButton = new BButton("Reset");
		_resetButton->setForm(Form_IconAlone);
		_resetButton->setShortcut("CTRL+R");

		_insertButton = new BButton("Insert");
		_insertButton->setShortcut("CTRL+I");
		_insertButton->setMenu(_insertMenu);

		_canvasButton = new BButton("Canvas");
		_canvasButton->setMenu(_canvasMenu);

		_modifyButton = new BButton("modify");
		_modifyButton->setMenu(_modifyMenu);

		BWidget* zoomWidget = new BWidget("zoom");
		zoomWidget->setSizePolicy(Policy_Preferred);
		{
			BLabel* zoomLabel = new BLabel("Zoom");
			_zoomSlider = new BSlider(1, 1000);
			_zoomSlider->setMinWidth(160);
			_zoomSlider->setHeightPolicy(Policy_Preferred);
			{
				BLayout* leftLayout = new BLayout(_zoomSlider, Part_Left);
				_zoomInArrow = new BButton('-');
				_zoomInArrow->setForm(Form_IconAlone);
				_zoomInArrow->setIconSize(12);
				_zoomInArrow->setSizePolicy(Policy_Preferred);
				_zoomInArrow->setBorder(0);
				leftLayout->setWidget(_zoomInArrow, Align_Center);

				BLayout* rightLayout = new BLayout(_zoomSlider, Part_Right);
				_zoomOutArrow = new BButton('+');
				_zoomOutArrow->setForm(Form_IconAlone);
				_zoomOutArrow->setIconSize(12);
				_zoomOutArrow->setSizePolicy(Policy_Preferred);
				_zoomOutArrow->setBorder(0);
				rightLayout->setWidget(_zoomOutArrow, Align_Center);
			}
			_zoomSpinBox = new BSpinBox(1, 1000);
			_zoomSpinBox->setSizePolicy(Policy_Preferred);
			_resetZoomButton = new BButton("reset-zoom");
			_resetZoomButton->setForm(Form_IconAlone);
			_resetZoomButton->setSizePolicy(Policy_Preferred);
			_resetZoomButton->setIconSize(16);

			BHBoxLayout* hlayout = new BHBoxLayout(zoomWidget);
			hlayout->addWidget(zoomLabel);
			hlayout->addWidget(_zoomSlider);
			hlayout->addWidget(_zoomSpinBox);
			hlayout->addWidget(_resetZoomButton);
		}

		BButton* turnHorButton = new BButton(_pixmapMenu->action("turn-hor"));
		turnHorButton->setForm(Form_IconAlone);

		BButton* turnVerButton = new BButton(_pixmapMenu->action("turn-ver"));
		turnVerButton->setForm(Form_IconAlone);

		BButton* rollLeftButton = new BButton(_pixmapMenu->action("roll-left"));
		rollLeftButton->setForm(Form_IconAlone);

		BButton* rollRightButton = new BButton(_pixmapMenu->action("roll-right"));
		rollRightButton->setForm(Form_IconAlone);

		toolsLayout->addWidget(_openButton);
		toolsLayout->addWidget(_saveButton);
		toolsLayout->addWidget(_resetButton);
		toolsLayout->addWidget(_insertButton);
		toolsLayout->addWidget(_canvasButton);
		toolsLayout->addWidget(_modifyButton);
		toolsLayout->addSpacer(3);
		toolsLayout->addWidget(zoomWidget);
		toolsLayout->addSpring();
		toolsLayout->addWidget(turnHorButton);
		toolsLayout->addWidget(turnVerButton);
		toolsLayout->addWidget(rollLeftButton);
		toolsLayout->addWidget(rollRightButton);
		toolsLayout->addSpring();
	}

	BWidget* leftWidget = new BWidget("left");
	leftWidget->setWidthPolicy(Policy_Preferred);
	{
		BButton* dragButton = new BButton("drag");
		dragButton->setForm(Form_IconAlone);
		dragButton->setAsset(new DragLayerFilter());

		BButton* cutoffButton = new BButton("cutoff");
		cutoffButton->setForm(Form_IconAlone);
		cutoffButton->setTips("Cutoff to new layer");
		cutoffButton->setAsset(new CutoffOperation());

		BButton* taosuoButton = new BButton("taosuo");
		taosuoButton->setForm(Form_IconAlone);

		BButton* paintButton = new BButton("paint");
		paintButton->setForm(Form_IconAlone);
		paintButton->setAsset(new PaintOperation());

		BButton* eraseButton = new BButton("erase");
		eraseButton->setForm(Form_IconAlone);
		eraseButton->setAsset(new EraseOperation());

		BVBoxLayout* vlayout = new BVBoxLayout(leftWidget);
		vlayout->addWidget(dragButton);
		vlayout->addWidget(cutoffButton);
		vlayout->addWidget(taosuoButton);
		vlayout->addWidget(paintButton);
		vlayout->addWidget(eraseButton);
		vlayout->addSpring();

		_buttonGroup = new BButtonGroup();
		_buttonGroup->addButton(cutoffButton);
		_buttonGroup->addButton(dragButton);
		_buttonGroup->addButton(taosuoButton);
		_buttonGroup->addButton(paintButton);
		_buttonGroup->addButton(eraseButton);
	}

	BVBoxLayout* centerLayout = new BVBoxLayout();
	{
		_pixmapArea = new PixmapArea();

		BHBoxLayout* statusLayout = new BHBoxLayout();
		{
			_statusBar = new BStatusBar();

			BLabel* layerLabel = new BLabel("layer");
			_layerXSpinBox = new BSpinBox(-99999, 99999);
			_layerYSpinBox = new BSpinBox(-99999, 99999);

			BLabel* globalLabel = new BLabel("area");
			_globalXSpinBox = new BSpinBox(-99999, 99999);
			_globalYSpinBox = new BSpinBox(-99999, 99999);

			statusLayout->addWidget(_statusBar, 100);
			statusLayout->addWidget(layerLabel);
			statusLayout->addWidget(_layerXSpinBox);
			statusLayout->addWidget(_layerYSpinBox);
			statusLayout->addSpacer(10);
			statusLayout->addWidget(globalLabel);
			statusLayout->addWidget(_globalXSpinBox);
			statusLayout->addWidget(_globalYSpinBox);
		}
		centerLayout->addWidget(_pixmapArea);
		centerLayout->addLayout(statusLayout, 0);
	}

	_rightLayout = new BVBoxLayout();
	_rightLayout->setSplitable(true);
	_rightLayout->setSpacing(6);
	{
		_propertyWidget = new BScrollWidget();
		_propertyWidget->setAreaPolicy(Policy_Growing, Policy_Preferred);
		{
			_propertyWidget->setProperty("BWidget", new WidgetPanel());
			_propertyWidget->setProperty("BLabel", new LabelLayerPanel());
			_propertyWidget->setProperty("ImageLayer", new ImageLayerPanel());
			_propertyWidget->setProperty("LineStripe", new LineStripePanel());
			BListWidget* listWidget = new BListWidget();
			_propertyWidget->setProperty("list", listWidget);
		}
		_layerTableBoard = new LayerTableBoard();
		//_layerTableBoard->setColumnHeaderShown(false);
		_layerTableBoard->setColumnCount(3);
		_layerTableBoard->setColumnPolicy(2, Policy_Growing);
		_layerTableBoard->setAreaPolicy(Policy_Growing);
		_layerTableBoard->setHorizontalScrollHint(ScrollHint_None);
		_layerTableBoard->setSelectMode(Select_Multiple | Select_Rows);
		//_layerTableBoard->setHeightPolicy(Policy_Dynamic);
		{
			_arrowUpButton = new BButton(Graph_Arrow_Up_Fill);
			_arrowUpButton->setForm(Form_IconAlone);

			_arrowDownButton = new BButton(Graph_Arrow_Down_Fill);
			_arrowDownButton->setForm(Form_IconAlone);

			_layerInsertButton = new BButton("insert");
			_layerInsertButton->setForm(Form_IconAlone);
			_layerInsertButton->setTips("insert layer to the list.");

			_layerExportButton = new BButton("export");
			_layerExportButton->setForm(Form_IconAlone);
			_layerExportButton->setTips("export layer image to file.");

			_layerRemoveButton = new BButton("remove");
			_layerRemoveButton->setForm(Form_IconAlone);
			_layerRemoveButton->setTips("remove layer from the list.");
			_layerRemoveButton->setShortcut("DEL", _layerTableBoard);

			_layerCutoffButton = new BButton("Cutoff");
			_layerCutoffButton->setForm(Form_IconAlone);
			_layerCutoffButton->setTips("Cutoff image.");

			_imageSizeComboBox = new BComboBox();
			_imageSizeComboBox->addItem("20", 20);
			_imageSizeComboBox->addItem("40", 40);
			_imageSizeComboBox->addItem("80", 80);
			_imageSizeComboBox->setCurrentIndex(0);

			BHBoxLayout* buttonLayout = new BHBoxLayout(_layerTableBoard, Part_Top);
			buttonLayout->addWidget(_arrowUpButton);
			buttonLayout->addWidget(_arrowDownButton);
			buttonLayout->addWidget(_layerInsertButton);
			buttonLayout->addWidget(_layerExportButton);
			buttonLayout->addWidget(_layerRemoveButton);
			buttonLayout->addWidget(_layerCutoffButton);
			buttonLayout->addSpring();
			buttonLayout->addWidget(_imageSizeComboBox);
		}

		_rightLayout->addWidget(_propertyWidget);
		_rightLayout->addWidget(_layerTableBoard);
		_rightLayout->setWidthPolicy(Policy_Preferred | Policy_Dynamic);
	}

	BHBoxLayout* splitLayout = new BHBoxLayout();
	splitLayout->setSplitable(true);
	splitLayout->setSpacing(6);
	splitLayout->addWidget(leftWidget, 0);
	splitLayout->addLayout(centerLayout, 10);
	splitLayout->addLayout(_rightLayout);

	BVBoxLayout* layout = new BVBoxLayout(this);
	layout->addLayout(toolsLayout, 0);
	layout->addLayout(splitLayout);

	connect(_openButton, Signal_Clicked, &MainWindow::slotOpenButtonClicked);
	connect(_saveButton, Signal_Clicked, &MainWindow::slotSaveButtonClicked);
	connect(_resetButton, Signal_Clicked, &MainWindow::slotResetButtonClicked);
	connect(_insertMenu, Signal_Triggered, &MainWindow::slotInsertMenuTriggered);

	connect(_modifyMenu, Signal_Triggered, &MainWindow::slotModifyMenuTrigger);
	connect(_zoomSlider, Signal_ValueChanged, &MainWindow::slotZoomValueChanged);
	connect(_zoomInArrow, Signal_Clicked, &MainWindow::slotZoomInArrowClicked);
	connect(_zoomOutArrow, Signal_Clicked, &MainWindow::slotZoomOutArrowClicked);
	connect(_zoomSpinBox, Signal_EditFinished, &MainWindow::slotZoomEditFinished);
	connect(_resetZoomButton, Signal_Clicked, &MainWindow::slotResetZoomButtonClicked);
	connect(_buttonGroup, Signal_Checked, &MainWindow::slotButtonGroupChecked);

	connect(_arrowUpButton, Signal_Clicked, &MainWindow::slotArrowUpClicked);
	connect(_arrowDownButton, Signal_Clicked, &MainWindow::slotArrowDownClicked);
	connect(_layerInsertButton, Signal_Clicked, &MainWindow::slotLayerInsertClicked);
	connect(_layerExportButton, Signal_Clicked, &MainWindow::slotLayerExportClicked);
	connect(_layerRemoveButton, Signal_Clicked, &MainWindow::slotLayerRemoveClicked);
	connect(_layerCutoffButton, Signal_Clicked, &MainWindow::slotCutoffButtonClicked);
	connect(_imageSizeComboBox, Signal_ValueChanged, &MainWindow::slotImageSizeChanged);
	connect(_layerTableBoard, Signal_ItemSelected, &MainWindow::slotLayerItemSelected);

	connect(_pixmapArea, Signal_RightClicked, &MainWindow::slotPixmapAreaRightClicked);
	connect(_pixmapArea, Signal_DoubleClicked, & MainWindow::slotPixmapAreaDoubleClicked);
	connect(_pixmapArea, Signal_SelectionChanged, &MainWindow::slotPixmapAreaSelectionChanged);
	connect(_pixmapArea, Signal_Remove, &MainWindow::slotPixmapAreaLayerRemoved);
	connect(_pixmapArea, Signal_DragDropped, &MainWindow::slotPixmapAreaDragDropped);
	connect(_pixmapArea, "zoom-changed", &MainWindow::slotPixmapAreaZoomChanged);
	connect(_pixmapArea, "operation-escape", &MainWindow::slotPixmapAreaOperationEscape);

	connect("layer-arranged", &MainWindow::slotWidgetOrderAdjusted);
	connect("insert-layer", &MainWindow::slotInsertImageLayer);
	connect("remove-layer", &MainWindow::slotRemoveImageLayer);
	connect("layer-point", &MainWindow::slotLayerPoint);
	connect("area-point", &MainWindow::slotAreaPoint);
	connect("apply-operation", &MainWindow::slotApplyOperation);
	connect("remove-operation", &MainWindow::slotRemoveOperation);
	connect("selection", &MainWindow::slotSelection);

	_zoomSlider->setValue(100);

	_canvasWidget->setAsset(_pixmapArea);

	_mainEventFilter = new BEventFilter();
	_pixmapArea->pixmap()->setSize(100, 100);
	_pixmapArea->setGridDrakness(100);
	_pixmapArea->setEventFilter(_mainEventFilter);

	freshMenus();
}
MainWindow::~MainWindow()
{

}

bool MainWindow::openImage(const BString& fileName)
{
	BObjectHolder object = ReadFile(fileName);
	if (BImage* image = object.as<BImage>())
	{
		BPixmap* pixmap = _pixmapArea->pixmap();
		pixmap->setSize(image->size());
		_zoomSlider->setValue(100);

		ImageLayer* layer = new ImageLayer(image);
		this->emit("insert-layer", layer);
		BApplication::setCurrentPath(fileName.path());
		return true;
	}
	if (BIcon* icon = object.as<BIcon>())
	{
		BSize canvasSize;
		for (int i = 0; i < State_Max; i++)
		{
			BImage* image = icon->image((State)i);
			if (image)
			{
				ImageLayer* layer = new ImageLayer(image);
				this->emit("insert-layer", layer);
				if (canvasSize.width() < image->width())
					canvasSize.width() = image->width();
				if (canvasSize.height() < image->height())
					canvasSize.height() = image->height();
			}
		}
		BPixmap* pixmap = _pixmapArea->pixmap();
		pixmap->setSize(canvasSize);
		_zoomSlider->setValue(100);
		BApplication::setCurrentPath(fileName.path());
		return true;
	}
	return false;
}

bool MainWindow::loadProject(const BString& fileName)
{
	if (fileName.endWith(".idx"))
	{
		BXmlDocument document;
		if(BXmlNode* root = document.load(fileName))
		{

		}
	}
	if (fileName.endWith(".ids"))
	{
		BSonDocument document;
		if (BSonNode* root = document.load(fileName))
		{

		}
	}
	return true;
}
bool MainWindow::saveProject(const BString& fileName)
{
	if (fileName.endWith(".idx"))
	{
		BXmlDocument document;
		if (BXmlNode* root = document.load(fileName))
		{

		}
	}
	if (fileName.endWith(".ids"))
	{
		BSonDocument document;
		if (BSonNode* root = document.load(fileName))
		{

		}
	}
	return true;
}

BString MainWindow::findValidName(const BString& name)
{
	BString realName;
	int number = 0;
	while (number < 9999)
	{
		realName.reset();
		realName << name << number++;
		if (_layerTableBoard->itemOfText(realName))
			continue;
		break;
	}
	return realName;
}
void MainWindow::freshMenus()
{
	bool selected = _pixmapArea->selectedWidgets().size();
	_pixmapMenu->action("turn-hor")->setEnabled(selected);
	_pixmapMenu->action("turn-ver")->setEnabled(selected);
	_pixmapMenu->action("roll-left")->setEnabled(selected);
	_pixmapMenu->action("roll-right")->setEnabled(selected);
	_pixmapMenu->menu("Align To")->setEnabled(selected);
}
void MainWindow::insertLayer(BWidget* widget)
{
	BPixmap* pixmap = _pixmapArea->pixmap();
	if (widget->size() != pixmap->size())
	{
		BRect view = _pixmapArea->area() & _pixmapArea->centerRect();
		view = _pixmapArea->mapToPixmap(view);
		BRect rect = view.align(Align_Center, widget->size());
		widget->setRect(rect);
	}

	pixmap->addWidget(widget);

	BButton* button = new BButton();
	button->setName("eye");
	button->setForm(Form_IconAlone);
	button->setCheckable(true);
	button->setChecked(true);
	connect(button, Signal_Checked, &MainWindow::slotEyeButtonChecked);

	int row = _layerTableBoard->addRows(1);
	int imageSize = _imageSizeComboBox->value();
	_layerTableBoard->setRowPolicy(row, Policy_Preferred);
	_layerTableBoard->setRowLabel(row, row);
	_layerTableBoard->setRowAsset(row, widget);

	BImage* preview = new BImage(Format_RGBA);
	_layerTableBoard->setItem(row, 0, button)->setAlign(Align_Center);
	_layerTableBoard->setItem(row, 1, preview)->setIconSize(imageSize);
	_layerTableBoard->setItem(row, 2, widget->title())->setAlign(Align_LeftCenter);

	connect(widget, Signal_Renamed, &MainWindow::slotImageLayerRenamed);
	connect(widget, Signal_Framed, &MainWindow::slotImageLayerFramed);

	_pixmapArea->clearSelection();
	_pixmapArea->select(widget);
}

void MainWindow::slotCopyShortcutTriggered()
{
	if (BTableItem* item = _layerTableBoard->selectedItem())
	{
		ImageLayer* layer = _layerTableBoard->rowAsset(item->row());
		BSystem::SetClippedValue(layer->clone());
	}
}
void MainWindow::slotPasteShortcutTriggered()
{
	ImageLayer* layer = BSystem::GetClippedValue();
	if (BImage* image = BSystem::GetClippedValue())
	{
		BString title = image->fileName().name();
		title -= title.dext();
		layer = new ImageLayer();
		layer->setTitle(title);
		layer->setImage(image);
		layer->setSize(image->size());
	}
	if (layer)
	{
		BPixmap* pixmap = _pixmapArea->pixmap();
		pixmap->addWidget(layer);
		BString title = findValidName(layer->title());
		layer->setTitle(title);

		BButton* button = new BButton();
		button->setName("eye");
		button->setForm(Form_IconAlone);
		button->setCheckable(true);
		button->setChecked(true);
		connect(button, Signal_Checked, &MainWindow::slotEyeButtonChecked);

		int row = _layerTableBoard->rowCount();
		if (BTableItem* item = _layerTableBoard->selectedItem())
		{
			row = item->row();
			_layerTableBoard->insertRows(row, 1);
		}
		else
		{
			_layerTableBoard->addRows(1);
		}
		int imageSize = _imageSizeComboBox->value();
		_layerTableBoard->setRowPolicy(row, Policy_Preferred);
		_layerTableBoard->setRowLabel(row, row);
		_layerTableBoard->setRowAsset(row, layer);
		_layerTableBoard->setItem(row, 0, button)->setAlign(Align_Center);
		BImage* preview = new BImage(Format_RGBA);
		_layerTableBoard->setItem(row, 1, preview)->setIconSize(imageSize);
		_layerTableBoard->setItem(row, 2, layer->title());
	}
	BSystem::SetClippedValue(BValue());
}

void MainWindow::slotOpenButtonClicked(BObject* object, const BValue& value)
{
	const BStringList& fileNamelst = BFileDialog::OpenFiles(this, "Open Image File");
	for (int i = 0; i < fileNamelst.size(); i++)
	{
		const BString& fileName = fileNamelst[i];
		if (fileName.size())
		{
			openImage(fileName);
		}
	}
}
void MainWindow::slotSaveButtonClicked(BObject* object, const BValue& value)
{
	BString fileName = BFileDialog::SaveFile(this, "Save Image File", "", "*.iex;*.ies;*.png;*.jpg;*.bmp;*.tiff");
	if (fileName.size())
	{
		if (BFile::Exist(fileName))
		{
			if (Button_No == BMessageBox::Warning("File is exist, Do you want to overlap it ?", Button_Yes | Button_No, Button_No))
				return;
		}
		if (fileName.endWith(".ies") || fileName.endWith(".iex"))
		{
			saveProject(fileName);
		}
		else
		{
			BImage* image = _pixmapArea->image();
			if (WriteFile<BImage>(fileName, image))
			{
				BMessageBox::Information("Save image successful !");
			}
		}
	}
}
void MainWindow::slotResetButtonClicked(BObject* object, const BValue& value)
{
	_pixmapArea->clearSelection();
	_pixmapArea->pixmap()->clearWidgets();
	_layerTableBoard->clearItems();
}
void MainWindow::slotInsertMenuTriggered(BObject* object, const BValue& value)
{
	const BAction* action = value;
	if (action->text() == "Image")
	{
		const BStringList& fileNames = BFileDialog::OpenFiles(this, "Import Image Files");
		for (int i = 0; i < fileNames.size(); i++)
		{
			const BString& fileName = fileNames[i];
			BObjectHolder object = ReadFile(fileName);
			if (BImage* image = object.as<BImage>())
			{
				ImageLayer* layer = new ImageLayer(image);
				_pixmapArea->clearSelection();
				emit("insert-layer", layer);
			}
		}
	}
	else if (action->text() == "Label")
	{
		BLabel* label = new BLabel("AaBbCc");
		label->setTitle("label");
		_pixmapArea->clearSelection();
		emit("insert-layer", label);
	}
	else if (action->text() == "Stripe")
	{
		LineStripe* layer = new LineStripe();
		layer->setTitle("line-stripe");
		_pixmapArea->clearSelection();
		emit("insert-layer", layer);
	}
}

void MainWindow::slotModifyMenuTrigger(BObject* object, const BValue& value)
{
	if (BAction* action = value)
	{
		if (action->text() == "replace")
		{
			if (_replaceDialog.empty())
			{
				_replaceDialog = new ReplaceDialog();
				connect(_replaceDialog, Signal_Close, &MainWindow::slotReplaceDialogClosed);
			}
			_replaceDialog->setParent(this);
			_replaceDialog->popup();
		}
	}
}
void MainWindow::slotZoomValueChanged(BObject* object, const BValue& value)
{
	int zoom = value;
	_pixmapArea->setZoom(zoom);
	_zoomSpinBox->setValue(zoom);
	_resetZoomButton->setEnabled(zoom != 100);
}
void MainWindow::slotZoomInArrowClicked(BObject* object, const BValue& value)
{
	_zoomSlider->decrease();
}
void MainWindow::slotZoomOutArrowClicked(BObject* object, const BValue& value)
{
	_zoomSlider->increase();
}
void MainWindow::slotZoomEditFinished(BObject* object, const BValue& value)
{
	int zoom = value;
	_zoomSlider->setValue(zoom);
}
void MainWindow::slotResetZoomButtonClicked()
{
	_zoomSlider->setValue(100);
}
void MainWindow::slotButtonGroupChecked(BObject* object, const BValue& value)
{
	if (BButton* button = value)
	{
		BEventFilter* operation = button->asset();
		if (button->checked())
		{
			this->emit("apply-operation", operation);
		}
		else
		{
			this->emit("remove-operation", operation);
		}
	}
}
void MainWindow::slotApplyOperation(BObject* object, const BValue& value)
{
	BEventFilter* operation = value;
	_mainEventFilter->addChild(operation);
}
void MainWindow::slotRemoveOperation(BObject* object, const BValue& value)
{
	BEventFilter* operation = value;
	_mainEventFilter->removeChild(operation);
}
void MainWindow::slotSelection(BObject* object, const BValue& value)
{
	BPolygon& polygon = value;
	//_polygons.append(polygon);
}

void MainWindow::slotArrowUpClicked()
{
	if (BTableItem* item = _layerTableBoard->selectedItem())
	{
		int row = item->row();
		ImageLayer* layer = _layerTableBoard->rowAsset(row);
		_layerTableBoard->moveRow(row, row - 1);
		layer->setIndex(row - 1);
	}
}
void MainWindow::slotArrowDownClicked()
{
	if (BTableItem* item = _layerTableBoard->selectedItem())
	{
		int row = item->row();
		ImageLayer* layer = _layerTableBoard->rowAsset(row);
		_layerTableBoard->moveRow(row, row + 1);
		layer->setIndex(row + 1);
	}
}
void MainWindow::slotLayerInsertClicked()
{
	if (_createLayerDialog.empty())
	{
		_createLayerDialog = new CreateLayerDialog(this);
	}
	BStringList namelst;
	for (int i = 0; i < _layerTableBoard->rowCount(); i++)
	{
		ImageLayer* layer = _layerTableBoard->rowAsset(i);
		namelst.append(layer->name());
	}
	_createLayerDialog->setNameList(namelst);
	if (_createLayerDialog->execute())
	{
		emit("insert-layer", _createLayerDialog->asset());
		_createLayerDialog->setAsset(BValue());
	}
}
void MainWindow::slotLayerRemoveClicked()
{
	while (BTableItem* item = _layerTableBoard->selectedItem())
	{
		ImageLayer* layer = _layerTableBoard->rowAsset(item->row());
		emit("remove-layer", layer);
	}
}
void MainWindow::slotCutoffButtonClicked()
{
	static CutoffImageDialog* dialog = new CutoffImageDialog(this);
	if (BTableItem* item = _layerTableBoard->selectedItem())
	{
		ImageLayer* layer = _layerTableBoard->rowAsset(item->row());
		dialog->setImage(layer->image());
		bool ret = dialog->execute();
		if (ret)
		{
			BImage* image = dialog->image();
			ImageLayer* newlayer = new ImageLayer(image);
			BString title = findValidName(layer->title());
			newlayer->setTitle(title);
			this->emit("insert-layer", newlayer);
		}
	}
}
void MainWindow::slotLayerExportClicked()
{
	BWidget* widget = _pixmapArea->selectedWidgets().first();
	if (ImageLayer* layer = dynamic_cast<ImageLayer*>(widget))
	{
		BString fileName = BFileDialog::SaveFile(this, "Save Image File");
		if (fileName.size())
		{
			BImage* image = layer->image();
			bool ret = WriteFile<BImage>(fileName, image);
		}
	}
}
void MainWindow::slotImageSizeChanged(BObject* object, const BValue& value)
{
	int imageSize = _imageSizeComboBox->value();
	for (int r = 0; r < _layerTableBoard->rowCount(); r++)
	{
		_layerTableBoard->item(r, 1)->setIconSize(imageSize);
	}
}
void MainWindow::slotLayerItemSelected(BObject* object, const BValue& value)
{
	BTableItem* item = value;
	if (item->selected())
	{
		BWidget* widget = _layerTableBoard->rowAsset(item->row());
		_pixmapArea->select(widget);
	}
	else
	{
		BWidget* widget = _layerTableBoard->rowAsset(item->row());
		_pixmapArea->unselect(widget);
	}
}

void MainWindow::slotEyeButtonChecked(BObject* object, const BValue& value)
{
	for (int r = 0; r < _layerTableBoard->rowCount(); r++)
	{
		BTableItem* item = _layerTableBoard->item(r, 0);
		if (item->widget() == object)
		{
			BWidget* widget = _layerTableBoard->rowAsset(r);
			widget->setVisible(value);
		}
	}
}
void MainWindow::slotReplaceDialogClosed(BObject* object, const BValue& value)
{
	_replaceDialog->setParent(0);
}

void MainWindow::slotPixmapAreaLayerRemoved(BObject* object, const BValue& value)
{
	if (ImageLayer* layer = value)
	{
		int row = _layerTableBoard->rowOfAsset(layer);
		if (row < _layerTableBoard->rowCount())
		{
			_layerTableBoard->removeRow(row);
		}
	}
}
void MainWindow::slotPixmapAreaZoomChanged(BObject* object, const BValue& value)
{
	int zoom = value;
	_zoomSlider->setValue(zoom);
}
void MainWindow::slotPixmapAreaSelectionChanged(BObject* object, const BValue& value)
{
	_propertyWidget->clearWidgets();
	const BWidgetSet& selection = value;
	if (selection.size() == 1)
	{
		BWidget* widget = selection.first();
		for (int i = 0; i < widget->typeCount(); i++)
		{
			const char* type = widget->typeName(i);
			if (BWidget* panel = _propertyWidget->property(type))
			{
				panel->setAsset(widget);
				_propertyWidget->addWidget(panel);
			}
		}
		freshMenus();
	}
	else if (selection.size() > 1)
	{
		BListWidget* listWidget = _propertyWidget->property("list");
		listWidget->clearItems();
		for (int i = 0; i < selection.size(); i++)
		{
			BWidget* widget = selection[i];
			listWidget->addItem(widget->title())->setAsset(widget);
		}
		_propertyWidget->addWidget(listWidget);
	}
	BIntArray selectedRows;
	for (int i = 0; i < selection.size(); i++)
	{
		BWidget* widget = selection[i];
		int row = _layerTableBoard->rowOfAsset(widget);
		selectedRows.append(row);
	}
	_layerTableBoard->setSelection(selectedRows);
}
void MainWindow::slotPixmapAreaOperationEscape(BObject* object, const BValue& value)
{
	if (BButton* button = _buttonGroup->buttonOfAsset(value))
	{
		button->setChecked(false);
	}
}
void MainWindow::slotPixmapAreaRightClicked(BObject* object, const BValue& value)
{
	const BPoint& pos = value;
	_pixmapMenu->setParent(_pixmapArea);
	_pixmapMenu->setPos(pos);
	_pixmapMenu->popup();
}
void MainWindow::slotPixmapAreaDoubleClicked(BObject* object, const BValue& value)
{
	_canvasButton->click();
}
void MainWindow::slotPixmapAreaDragDropped(BObject* object, const BValue& value)
{
	BDrag* drag = value;
	if (const BStringArray* fileNames = drag->value())
	{
		for (int i = 0; i < fileNames->size(); i++)
		{
			const BString& fileName = fileNames->at(i);
			BObjectHolder obj = ReadFile(fileName);
			ImageLayer* newlayer = new ImageLayer(obj.as<BImage>());
			//BString title = findValidName(image->fileName().name());
			//newlayer->setTitle(title);
			this->emit("insert-layer", newlayer);
		}
	}
}

void MainWindow::slotTurnHorActionTriggered(BObject* object, const BValue& value)
{
	BWidgetSet& widgets = _pixmapArea->selectedWidgets();
	for (int i = 0; i < widgets.size(); i++)
	{
		BWidget* widget = widgets[i];
		if (ImageLayer* layer = dynamic_cast<ImageLayer*>(widget))
		{
			BImage* image = layer->image();
			image->reverse(Orientation_Horizontal);
		}
	}
}
void MainWindow::slotTurnVerActionTriggered(BObject* object, const BValue& value)
{
	BWidgetSet& widgets = _pixmapArea->selectedWidgets();
	for (int i = 0; i < widgets.size(); i++)
	{
		BWidget* widget = widgets[i];
		if (ImageLayer* layer = dynamic_cast<ImageLayer*>(widget))
		{
			BImage* image = layer->image();
			image->reverse(Orientation_Vertical);
		}
	}
}
void MainWindow::slotRollLeftActionTriggered(BObject* object, const BValue& value)
{
	BWidgetSet& widgets = _pixmapArea->selectedWidgets();
	for (int i = 0; i < widgets.size(); i++)
	{
		BWidget* widget = widgets[i];
		if (ImageLayer* layer = dynamic_cast<ImageLayer*>(widget))
		{
			BImage* image = layer->image();
			image->roll(-1);
		}
	}
}
void MainWindow::slotRollRightActionTriggered(BObject* object, const BValue& value)
{
	BWidgetSet& widgets = _pixmapArea->selectedWidgets();
	for (int i = 0; i < widgets.size(); i++)
	{
		BWidget* widget = widgets[i];
		if (ImageLayer* layer = dynamic_cast<ImageLayer*>(widget))
		{
			BImage* image = layer->image();
			image->roll(1);
		}
	}
}
void MainWindow::slotAlignButtonClicked(BObject* object, const BValue& value)
{
	if (BButton* button = value)
	{
		Align align = button->asset();
		int zoom = _pixmapArea->zoom();
		float ratio = zoom / 100.0f;
		BRect prect = _pixmapArea->areaSize() / ratio;
		BWidgetSet& selectedWidgets = _pixmapArea->selectedWidgets();
		for (int i = 0; i < selectedWidgets.size(); i++)
		{
			BWidget* widget = selectedWidgets[i];
			BRect rect = prect.align(align, widget->size());
			widget->setRect(rect);
			this->emit("layer-moved", widget);
		}
	}
	_pixmapMenu->hide();
}

void MainWindow::slotWidgetOrderAdjusted(BObject* object, const BValue& value)
{
	BPixmap* pixmap = _pixmapArea->pixmap();
	pixmap->clearWidgets();
	for (int r = 0; r < _layerTableBoard->rowCount(); r++)
	{
		BWidget* widget = _layerTableBoard->rowAsset(r);
		pixmap->addWidget(widget);
	}
}
void MainWindow::slotInsertImageLayer(BObject* object, const BValue& value)
{
	if (BImage* image = value)
	{
		ImageLayer* layer = new ImageLayer(image);
		insertLayer(layer);
	}
	else if (ImageLayer* layer = value)
	{
		insertLayer(layer);
	}
	else if (BWidget* widget = value)
	{
		insertLayer(widget);
	}
}
void MainWindow::slotRemoveImageLayer(BObject* object, const BValue& value)
{
	ImageLayer* layer = value;
	if (BImage* image = value)
	{
		layer = _pixmapArea->findLayer(image);
	}
	if (layer)
	{
		_pixmapArea->unselect(layer);
		BPixmap* pixmap = _pixmapArea->pixmap();
		pixmap->removeWidget(layer);
		int row = _layerTableBoard->rowOfAsset(layer);
		_layerTableBoard->removeRow(row);
	}
}
void MainWindow::slotImageLayerRenamed(BObject* object, const BValue& value)
{
	int row = _layerTableBoard->rowOfAsset(object);
	if (BTableItem* item = _layerTableBoard->item(row, 2))
	{
		item->setText(value);
	}
}
void MainWindow::slotImageLayerFramed(BWidget* widget, const BValue& value)
{
	int row = _layerTableBoard->rowOfAsset(widget);
	if (BTableItem* item = _layerTableBoard->item(row, 1))
	{
		BImage* image = item->image();
		widget->capture(image);
		image->reverse(Orientation_Vertical);
		_layerTableBoard->fresh();
	}
}
void MainWindow::slotLayerPoint(BObject* object, const BValue& value)
{
	const BPoint& point = value;
	_layerXSpinBox->setValue(point.x());
	_layerYSpinBox->setValue(point.y());
}
void MainWindow::slotAreaPoint(BObject* object, const BValue& value)
{
	const BPoint& point = value;
	_globalXSpinBox->setValue(point.x());
	_globalYSpinBox->setValue(point.y());
}

void MainWindow::styleEvent(const BEvent& event)
{
	const BStyle* style = this->realStyle();
	for (int i = 0; i < _buttonGroup->buttonCount(); i++)
	{
		BButton* button = _buttonGroup->button(i);
		BIcon* icon = style->icon(button->text());
		button->setIcon(icon);
	}
	_openButton->setIcon(style->icon("open"));
	_saveButton->setIcon(style->icon("save"));
	_resetButton->setIcon(style->icon("reset"));
	_insertButton->setIcon(style->icon("insert"));
	_canvasButton->setIcon(style->icon("canvas"));
	_modifyButton->setIcon(style->icon("modify"));

	_zoomInArrow->setIcon(style->icon("zoom-in"));
	_zoomOutArrow->setIcon(style->icon("zoom-out"));
	_resetZoomButton->setIcon(style->icon("reset-zoom"));

	_arrowUpButton->setIconSize(style->font()->size() / 2);
	_arrowDownButton->setIconSize(style->font()->size() / 2);
	_layerInsertButton->setIcon(style->icon("insert"));
	_layerExportButton->setIcon(style->icon("export"));
	_layerRemoveButton->setIcon(style->icon("remove"));
	_layerCutoffButton->setIcon(style->icon("cutoff"));

	_arrowUpButton->setTips(style->text("tips-arrow-upper"));
	_arrowDownButton->setTips(style->text("tips-arrow-lower"));
	_layerInsertButton->setTips(style->text("tips-insert"));
	_layerExportButton->setTips(style->text("tips-export"));
	_layerRemoveButton->setTips(style->text("tips-remove"));
	_layerCutoffButton->setTips(style->text("tips-cutoff"));

	_pixmapMenu->action("turn-hor")->setTips(style->text("tips-turn-hor"));
	_pixmapMenu->action("turn-ver")->setTips(style->text("tips-turn-ver"));
	_pixmapMenu->action("roll-left")->setTips(style->text("tips-roll-left"));
	_pixmapMenu->action("roll-right")->setTips(style->text("tips-roll-right"));
	_pixmapMenu->flush();
}
void MainWindow::updateEvent(const BEvent& event)
{

}
